package com.wits.media;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;


/**
 * Created by zhengboyuan on 2018-03-12.
 */

public class COsdOverlayRender implements OsdOverlayRender {

    OsdOverlay  osdOverlay;
    ImageFrame  osdFrame;
    long    curTime;        /// seconds

    public COsdOverlayRender() {

    }

    @Override
    public boolean open(OsdOverlay overlay) {
        if (overlay == null) {
            return false;
        }

        osdOverlay = overlay;

        adjustParams(osdOverlay);

        return makeFrame();
    }

    @Override
    public OsdOverlay getOverlay() {
        return osdOverlay;
    }

    @Override
    public boolean draw(ImageFrame frame) {
        if (osdOverlay.left < 0 || osdOverlay.left >= frame.width) {
            return false;
        }

        if (osdOverlay.top < 0 || osdOverlay.top >= frame.height) {
            return false;
        }

        if (!makeFrame()) {
            return false;
        }

        YuvBlit.Plane videoPlane = new YuvBlit.Plane(frame.data, 0, frame.width, frame.height, frame.width);
        YuvBlit.YuvPlanes videoPlanes = YuvBlit.YuvPlanes.clipYV12(videoPlane, osdOverlay.left, osdOverlay.top, osdFrame.width, osdFrame.height);

        YuvBlit.Plane maskPlane = new YuvBlit.Plane(osdFrame.data, 0, osdFrame.width, osdFrame.height, osdFrame.width);
        YuvBlit.YuvPlanes maskPlanes = YuvBlit.YuvPlanes.clipYV12(maskPlane, 0, 0, osdFrame.width, osdFrame.height);

        int keyColor = Rgb.rgb(0, 0, 0);
        int fontColor = osdOverlay.color;
        if (osdOverlay.transparent) {
            if (hasFlags(osdOverlay, OsdOverlay.ANTI_ALIAS_FLAG)) {
                YuvBlit.blitYV12(maskPlanes, videoPlanes, keyColor, osdOverlay.alpha, fontColor);
            } else {
                YuvBlit.blitYV12(maskPlanes, videoPlanes, keyColor, osdOverlay.alpha);
            }
        } else {
            if (osdOverlay.alpha < 255) {
                YuvBlit.blitYV12Alpha(maskPlanes, videoPlanes, osdOverlay.alpha);
            } else {
                YuvBlit.blitYV12(maskPlanes, videoPlanes);
            }
        }

        return false;
    }

    @Override
    public void close() throws IOException {
        // pass
    }

    protected boolean makeFrame() {
        if (osdOverlay.type == OsdOverlay.TYPE_TEXT) {
            if (osdFrame == null) {
                osdFrame = makeTextFrame(osdOverlay.text);
            }
        } else if (osdOverlay.type == OsdOverlay.TYPE_DATETIME) {
            long seconds = getTime();
            if (seconds != curTime) {
                osdFrame = makeTimeFrame(osdOverlay.text);
            }
            curTime = seconds;
        } else if (osdOverlay.type == OsdOverlay.TYPE_IMAGE) {
            if (osdFrame == null) {
                osdFrame = makeImageFrame(osdOverlay.text);
            }
        }

        return true;
    }


    protected long getTime() {
        return System.currentTimeMillis() / 1000;
    }

    protected ImageFrame makeTimeFrame(String pattern) {
        try {
            Date date = new Date();
            SimpleDateFormat format = new SimpleDateFormat(pattern);
            String text = format.format(date);
            return makeTextFrame(text);
        } catch (Throwable t) {
            return null;
        }
    }

    protected ImageFrame makeImageFrame(String filepath) {
        Bitmap bitmap = null;
        if (osdOverlay.context != null) {
            int id = osdOverlay.context.getResources().getIdentifier(filepath, null, null);
            if (id != 0) {
                bitmap = BitmapFactory.decodeResource(osdOverlay.context.getResources(), id);
            } else {
                bitmap = BitmapFactory.decodeFile(filepath);
            }
        } else {
            bitmap = BitmapFactory.decodeFile(filepath);
        }

        if (bitmap == null) {
            return null;
        }
        return ImageFrameUtil.makeYv12(bitmap);
    }

    protected ImageFrame makeTextFrame(String text) {
        Bitmap bitmap = makeBitmap(text);
        if (bitmap == null) {
            return null;
        }
        return ImageFrameUtil.makeYv12(bitmap);
    }

    protected Bitmap makeBitmap(String text) {
        int flags = 0;
        if (hasFlags(osdOverlay, OsdOverlay.ANTI_ALIAS_FLAG)) {
            //flags = flags | Paint.ANTI_ALIAS_FLAG;
        }

        Paint paint = new Paint(flags);

        paint.setTextSize(osdOverlay.font.size);
        paint.setColor(osdOverlay.color);
        paint.setTextAlign(Paint.Align.LEFT);
        paint.setAlpha(osdOverlay.alpha);

        Typeface typeface = makeTypeface(osdOverlay.font);
        paint.setTypeface(typeface);

        float baseline = -paint.ascent(); // ascent() is negative
        int width = (int) (paint.measureText(text) + 0.5f); // round
        int height = (int) (baseline + paint.descent() + 0.5f);
        /// 确保是偶数
        width = (width / 2) * 2;
        height = (height / 2) * 2;

        Bitmap image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(image);

        if (!osdOverlay.transparent) {
            canvas.drawColor(osdOverlay.background);
        }

        canvas.drawText(text, 0, baseline, paint);
        return image;
    }

    public void adjustParams(OsdOverlay osdOverlay) {
        if (osdOverlay.font.size < OsdOverlay.MIN_FONT_SIZE) {
            osdOverlay.font.size = OsdOverlay.MIN_FONT_SIZE;
        } else if (osdOverlay.font.size > OsdOverlay.MAX_FONT_SIZE) {
            osdOverlay.font.size = OsdOverlay.MAX_FONT_SIZE;
        }

        if (osdOverlay.text == null) {
            osdOverlay.text = "";
        }

        // 确保是2的倍数
        osdOverlay.top = (osdOverlay.top / 2) * 2;
        osdOverlay.left = (osdOverlay.left / 2) * 2;
    }

    public Typeface makeTypeface(OsdOverlay.OsdFont osdFont) {
        int style = Typeface.NORMAL;
        if (osdFont.italic && osdFont.bold) {
            style = Typeface.BOLD_ITALIC;
        } else if (osdFont.italic) {
            style = Typeface.ITALIC;
        } else if (osdFont.bold) {
            style = Typeface.BOLD;
        }

        if (osdFont.name != null && !osdFont.name.isEmpty()) {
            Typeface typeface = Typeface.create(osdFont.name, style);
            return typeface;
        } else {
            return Typeface.create(Typeface.DEFAULT, style);
        }
    }

    boolean hasFlags(OsdOverlay  osdOverlay, int flag) {
        return (osdOverlay.flags & flag) != 0;
    }
}
